package com.xcity.game.task.detector;

import java.util.List;
import java.util.Set;

import com.alibaba.fastjson.JSONObject;
import com.xcity.game.battle.pve.PVEStage;
import com.xcity.game.item.drop.Drop;
import com.xcity.game.item.drop.impl.ItemDrop;
import com.xcity.game.task.Task;
import com.xcity.game.task.Task.State;
import com.xcity.game.task.TaskDetector;
import com.xcity.game.task.TaskDetectorLabel;

/**
 * <pre>
 * 挑战pve关卡任务
 * 4个参数:
 * 1.关卡id(0:任意关卡)
 * 2.次数
 * 3.掉落物品id(可为空)
 * 4.掉落物品数(可为空)
 * </pre>
 * @author yang.li
 *
 */
@TaskDetectorLabel(TaskDetector.PVE_FIGHT)
public class PVETaskDetector implements TaskDetector {

	static final String KEY = String.valueOf(PVE_FIGHT);
	
	@Override
	public boolean isFinish(Task task) {
		if (task.getTemplate().getConditionId() != PVE_FIGHT) {
			return false;
		}
		if (task.getState() == State.FINISHED || task.getState() == State.REWARDED) {
			return true;
		}
		// { 1: { stageId: { star: n, items: { id: count } } } }
		JSONObject stages = task.getArchive().getJSONObject(KEY);
		if (stages == null) {
			return false;
		}
		int[] conds = task.getTemplate().getConditions();
		int stageId = conds[0];
		if (stageId == 0) {
			return detectAll(conds, stages);
		}
		JSONObject stage = stages.getJSONObject(String.valueOf(stageId));
		return detect(conds, stage);
	}
	
	private boolean detect(int[] conds, JSONObject stage) {
		if (detectCount(conds[1], stage) > 0) {
			return false;
		}
		if (conds.length > 3 && detectItem(conds[2], conds[3], stage) > 0) {
			return false;
		}
		return true;
	}
	
	private boolean detectAll(int[] conds, JSONObject stages) {
		int count = conds[1];
		int itemId = 0, itemCount = 0;
		if (conds.length > 3) {
			itemId = conds[2];
			itemCount = conds[3];
		}
		Set<String> stageIds = stages.keySet();
		for (String stageId : stageIds) {
			JSONObject stage = stages.getJSONObject(stageId);
			count = detectCount(count, stage);
			itemCount = detectItem(itemId, itemCount, stage);
			if (count <= 0 && itemCount <= 0) {
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 检测次数，返回达成该条件还需挑战次数
	 * @param count
	 * @param stage
	 * @return
	 */
	private int detectCount(int count, JSONObject stage) {
		if (count > 0 && stage != null) {
			count -= stage.getIntValue("count");
		}
		return count < 0 ? 0 : count;
	}
	
	/**
	 * 检测掉落物品，返回达成该条件还需该物品数量
	 * @param itemId
	 * @param count
	 * @param stage
	 * @return
	 */
	private int detectItem(int itemId, int count, JSONObject stage) {
		if (count > 0 && stage != null) {
			JSONObject items = stage.getJSONObject("items");
			if (items != null) {
				count -= items.getIntValue(String.valueOf(itemId));
			}
		}
		return count < 0 ? 0 : count;
	}
	
//	private boolean detect(int[] conds, JSONObject stage) {
//		int count = conds[1];
//		if (stage == null || stage.getIntValue("count") < count) {
//			return false;
//		}
//		if (conds.length > 3) {
//			int itemId = conds[2], itemCount = conds[3];
//			JSONObject items = stage.getJSONObject("items");
//			if (items == null || items.getIntValue(String.valueOf(itemId)) < itemCount) {
//				return false;
//			}
//		}
//		return true;
//	}

	@Override
	public void onArchive(Task task, Object... vals) {
		String stageId = String.valueOf(((PVEStage) vals[1]).getId());
//		int star = (int) vals[2];
		List<Drop> drops = (List<Drop>) vals[3];
		// { 1: { stageId: { count: n, items: { id: count } } } }
		JSONObject stages = task.getArchive().getJSONObject(KEY);
		if (stages == null) {
			stages = new JSONObject();
			task.getArchive().put(KEY, stages);
		}
		JSONObject stage = stages.getJSONObject(stageId);
		if (stage == null) {
			stage = new JSONObject(2);
			stages.put(stageId, stage);
		}
		stage.put("count", stage.getIntValue("count") + 1); // 累计次数
			
		JSONObject items = stage.getJSONObject("items");
		if (items == null) {
			items = new JSONObject();
			stage.put("items", items);
		}
		for (int i = 0; i < drops.size(); i++) {
			Drop d = drops.get(i);
			if (d instanceof ItemDrop) {
				ItemDrop itemDrop = (ItemDrop) d;
				String itemId = String.valueOf(itemDrop.getId());
				int c = items.getIntValue(itemId) + itemDrop.getCount();
				items.put(itemId, c);
			}
		}
	}
	
}
